import json
import urllib
import sys
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
import time
from datetime import datetime
import csv

def main():
    max_retries = 5  # 设置最大重试次数
    retries = 0

    while retries < max_retries:
        # 生成时间戳
        timestamp = datetime.now().strftime('%Y%m%d%H%M%S')

        # 设置查询参数
        city = "101040100"
        query = "java"
        page = "3"

        # 设置Chrome驱动
        chrome_options = Options()
        # chrome_options.add_argument("--headless")  # 启用无头模式
        # chrome_options.add_argument("--disable-gpu")  # 禁用GPU加速
        # chrome_options.add_argument("--no-sandbox")  # 禁用沙盒模式
        chrome_options.add_argument("--window-size=1920x1080")  # 设置窗口大小
        service = Service(ChromeDriverManager().install())
        driver = webdriver.Chrome(service=service, options=chrome_options)

        # 打开目标网页
        driver.get(f"https://www.zhipin.com/web/geek/job?query={query}&city={city}&page={page}")

        # 等待页面加载
        time.sleep(20)

        # 获取XHR请求的数据
        xhr_url = "https://www.zhipin.com/wapi/zpgeek/search/joblist.json"
        params = {
            "scene": "1",
            "query": query,
            "city": city,
            "experience": "",
            "payType": "",
            "partTime": "",
            "degree": "",
            "industry": "",
            "scale": "",
            "stage": "",
            "position": "",
            "jobType": "",
            "salary": "",
            "multiBusinessDistrict": "",
            "multiSubway": "",
            "page":page,
            "pageSize": "30"
        }

        # 使用Selenium发送请求
        response = driver.execute_script(f"""
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '{xhr_url}?{urllib.parse.urlencode(params)}', false);
            xhr.setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
            xhr.setRequestHeader('Referer', 'https://www.zhipin.com/web/geek/job?query={query}&city={city}&page=1');
            xhr.send(null);
            return xhr.responseText;
        """)
        data = json.loads(response)
        print(data)

        # 检查 code 是否为 0
        if data.get('code') == 0:
            # 关闭浏览器
            driver.quit()

            # 创建并进入 bosszhipindata 目录
            output_dir = "bosszhipindata"
            if not os.path.exists(output_dir):
                os.makedirs(output_dir)

            # 构建文件名
            json_filename = f"job-{city}-{query}-{timestamp}.json"
            csv_filename = f"job-{city}-{query}-{timestamp}.csv"

            # 将数据写入 JSON 文件
            with open(json_filename, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=4)

            print(f"数据已保存到 {json_filename} 文件中")

            # 读取 JSON 文件
            with open(json_filename, 'r', encoding='utf-8') as f:
                data = json.load(f)

            # 提取 jobList 数据
            job_list = data['zpData']['jobList']

            # # 定义 CSV 文件的字段
            # fieldnames = [
            #     'jobName', 'salaryDesc', 'jobExperience', 'jobDegree', 'cityName',
            #     'areaDistrict', 'businessDistrict', 'brandName', 'brandIndustry',
            #     'brandScaleName', 'welfareList', 'skills'
            # ]

            # 根据 jobList 中的字段顺序定义 fieldnames
            fieldnames = [
                'securityId', 'bossAvatar', 'bossCert', 'encryptBossId', 'bossName',
                'bossTitle', 'goldHunter', 'bossOnline', 'encryptJobId', 'expectId',
                'jobName', 'lid', 'salaryDesc', 'jobLabels', 'jobValidStatus', 'iconWord',
                'skills', 'jobExperience', 'daysPerWeekDesc', 'leastMonthDesc', 'jobDegree',
                'cityName', 'areaDistrict', 'businessDistrict', 'jobType', 'proxyJob',
                'proxyType', 'anonymous', 'outland', 'optimal', 'iconFlagList', 'itemId',
                'city', 'isShield', 'atsDirectPost', 'gps', 'encryptBrandId', 'brandName',
                'brandLogo', 'brandStageName', 'brandIndustry', 'brandScaleName', 'welfareList',
                'industry', 'contact', 'showTopPosition'
            ]

            # 写入 CSV 文件，使用 utf-8-sig 编码
            with open(csv_filename, 'w', newline='', encoding='utf-8-sig') as csvfile:
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

                # 写入表头
                writer.writeheader()

                # 写入数据行
                for job in job_list:
                    # 将列表转换为字符串以便写入 CSV
                    job['welfareList'] = ', '.join(job['welfareList'])
                    job['skills'] = ', '.join(job['skills'])

                    # 写入每一行数据
                    writer.writerow({
                        'securityId': job.get('securityId', ''),  # 职位的安全ID
                        'bossAvatar': job.get('bossAvatar', ''),  # BOSS的头像URL
                        'bossCert': job.get('bossCert', ''),  # BOSS的认证信息
                        'encryptBossId': job.get('encryptBossId', ''),  # 加密的BOSS ID
                        'bossName': job.get('bossName', ''),  # BOSS的名字
                        'bossTitle': job.get('bossTitle', ''),  # BOSS的职位头衔
                        'goldHunter': job.get('goldHunter', ''),  # 是否为金牌猎头
                        'bossOnline': job.get('bossOnline', ''),  # BOSS是否在线
                        'encryptJobId': job.get('encryptJobId', ''),  # 加密的职位ID
                        'expectId': job.get('expectId', ''),  # 预期ID
                        'jobName': job.get('jobName', ''),  # 职位名称
                        'lid': job.get('lid', ''),  # 职位的唯一标识符
                        'salaryDesc': job.get('salaryDesc', ''),  # 薪资描述
                        'jobLabels': job.get('jobLabels', ''),  # 职位标签
                        'jobValidStatus': job.get('jobValidStatus', ''),  # 职位有效性状态
                        'iconWord': job.get('iconWord', ''),  # 图标文字
                        'skills': job['skills'],  # 技能要求，已转换为逗号分隔的字符串
                        'jobExperience': job.get('jobExperience', ''),  # 工作经验要求
                        'daysPerWeekDesc': job.get('daysPerWeekDesc', ''),  # 每周工作天数描述
                        'leastMonthDesc': job.get('leastMonthDesc', ''),  # 最少工作月数描述
                        'jobDegree': job.get('jobDegree', ''),  # 学历要求
                        'cityName': job.get('cityName', ''),  # 城市名称
                        'areaDistrict': job.get('areaDistrict', ''),  # 区域名称
                        'businessDistrict': job.get('businessDistrict', ''),  # 商业区名称
                        'jobType': job.get('jobType', ''),  # 职位类型
                        'proxyJob': job.get('proxyJob', ''),  # 是否为代理职位
                        'proxyType': job.get('proxyType', ''),  # 代理类型
                        'anonymous': job.get('anonymous', ''),  # 是否匿名
                        'outland': job.get('outland', ''),  # 是否在外地区域
                        'optimal': job.get('optimal', ''),  # 是否为最优职位
                        'iconFlagList': job.get('iconFlagList', ''),  # 图标标志列表
                        'itemId': job.get('itemId', ''),  # 项目ID
                        'city': job.get('city', ''),  # 城市ID
                        'isShield': job.get('isShield', ''),  # 是否屏蔽
                        'atsDirectPost': job.get('atsDirectPost', ''),  # 是否直接投递
                        'gps': job.get('gps', ''),  # GPS坐标
                        'encryptBrandId': job.get('encryptBrandId', ''),  # 加密的品牌ID
                        'brandName': job.get('brandName', ''),  # 品牌名称
                        'brandLogo': job.get('brandLogo', ''),  # 品牌Logo URL
                        'brandStageName': job.get('brandStageName', ''),  # 品牌发展阶段名称
                        'brandIndustry': job.get('brandIndustry', ''),  # 品牌所属行业
                        'brandScaleName': job.get('brandScaleName', ''),  # 品牌规模名称
                        'welfareList': job['welfareList'],  # 福利列表，已转换为逗号分隔的字符串
                        'industry': job.get('industry', ''),  # 行业领域
                        'contact': job.get('contact', ''),  # 联系方式
                        'showTopPosition': job.get('showTopPosition', '')  # 是否展示为顶级职位
                    })

            print(f"数据已保存到 {csv_filename} 文件中")
            break  # 成功获取数据后退出循环
        else:
            print(f"Code is not 0, retrying... ({retries + 1}/{max_retries})")
            driver.quit()
            retries += 1
            time.sleep(5)  # 等待一段时间后重试

    if retries == max_retries:
        print(f"达到最大重试次数 {max_retries}，程序退出。")

if __name__ == "__main__":
    main()
